package main

import (
	"./encryption"
	"crypto/md5"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"
)

type res_struct struct {
	Authorasation string
	SecurityKey string
	bodyStr string
	Timestamp string
	token string
}


func sayHelloName(w http.ResponseWriter, r *http.Request){
	r.ParseForm()
	fmt.Println(r.Form)
	fmt.Println("path:", r.URL.Path)
	fmt.Println("cheme:", r.URL.Scheme)
	fmt.Println(r.Form["url_long"])
	for k,v := range r.Form{
		fmt.Println("key:", k)
		fmt.Println("val:", strings.Join(v,""))
	}
	fmt.Fprintf(w, "my Cryptography project")

}

func login(w http.ResponseWriter, r *http.Request){
	fmt.Println("method:", r.Method)
	if r.Method == "GET" {
		//获取时间戳
		curtime := time.Now().Unix()
		h := md5.New()
		io.WriteString(h, strconv.FormatInt(curtime, 10))
		token := fmt.Sprintf("%x", h.Sum(nil))
		pub_key := encryption.GetPKey();
		t, _ := template.ParseFiles("N:/GoLand/project/1005/resources/gtpl/webFase.gtpl")
		data := token + pub_key
		t.Execute(w, data)
	}else {
		t := time.Now()
		res, _ := ioutil.ReadAll(r.Body) //获取post的数据
		str := string(res)
		m := make(map[string]interface{})
		err := json.Unmarshal([]byte(str), &m)
		if err != nil {
			fmt.Println("err=", err)
			return
		}
		token := m["token"].(string)
		Authorasation := m["Authoration"].(string)
		SecurityKey := m["SecurityKey"].(string)
		bodyStr := m["bodyStr"].(string)
		timeStr := m["Timestamp"].(string)
		fmt.Println("Authorasation:"+Authorasation)
		fmt.Println("SecurityKey:"+SecurityKey)
		fmt.Println("bodyStr:"+bodyStr)
		fmt.Println("timeStr:"+timeStr)

		/* 判断时间戳 */
		/* 如果超过某个规定时间就可以进行丢弃等操作 */
		timeUnix:=time.Now().Unix()
		fmt.Println("timestamp:")
		fmt.Println(timeUnix, timeStr)


		/*利用RSA私钥从SecurityKey 中获取AESKey*/
		b, err := base64.StdEncoding.DecodeString(SecurityKey)
		AESKey_tmp := encryption.RSA_Decrypt(b,"private1.pem")
		AESKey := string(AESKey_tmp)
		fmt.Println("AESKey:"+AESKey)

		/* 利用AESKey解密获取bodystr */
		decodeBytes1, err := base64.StdEncoding.DecodeString(AESKey)
		tmp := string(decodeBytes1)
		decodeBytes2, err := base64.StdEncoding.DecodeString(bodyStr)
		bodystr_tmp := encryption.AesDecryptECB(decodeBytes2,[]byte(tmp));
		fmt.Println("bodystr:"+string(bodystr_tmp))

		/* md5对bodystr生成摘要 */
		md5Str := fmt.Sprintf("%x", md5.Sum(bodystr_tmp))
		fmt.Println("md5Str:"+md5Str)

		/* 使用RSA密钥对authoration中的signature进行解密 */
		b_tmp, err := base64.StdEncoding.DecodeString(Authorasation)
		rsaDecryptoStr_tmp := encryption.RSA_Decrypt(b_tmp,"private1.pem")
		rsaDecryptoStr := string(rsaDecryptoStr_tmp)
		fmt.Println("rsaDecryptoStr:"+rsaDecryptoStr)

		/* 比较md5Str 和 rsaDecryptoStr*/



		if token != ""{
			//验证合法性
			fmt.Println("token:"+token)
		}else{

		}
		//业务逻辑
		elapsed := time.Since(t)
		fmt.Println()
		fmt.Println("time elapsed:", elapsed)
	}
}

func upload(w http.ResponseWriter, r *http.Request){
	fmt.Println("method:", r.Method)
	if r.Method == "GET"{
		curtime := time.Now().Unix()
		h := md5.New()
		io.WriteString(h, strconv.FormatInt(curtime, 10))
		token := fmt.Sprintf("%x", h.Sum(nil))

		t, _ := template.ParseFiles("N:/GoLand/project/1005/resources/gtpl/upload.gtpl")
		t.Execute(w, token)
	}else{
		r.ParseMultipartForm(32 << 20)
		file, handler, err := r.FormFile("uploadfile")
		if err != nil{
			fmt.Println(err)
			return
		}
		defer file.Close()
		fmt.Fprintf(w, "%v", handler.Header)
		f, err :=os.OpenFile("N:/GoLand/project/1005/resources/files/" + handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
		if err != nil{
			fmt.Println(err)
			return
		}
		defer f.Close()
		io.Copy(f, file)
	}
}




func main()  {

	//设置访问的路由
	http.Handle("/resources/static/js/", http.StripPrefix("/resources/static/js/", http.FileServer(http.Dir("resources/static/js/"))))
	http.HandleFunc("/", sayHelloName)
	http.HandleFunc("/login", login)
	http.HandleFunc("/upload", upload)
	err := http.ListenAndServe(":9090",nil)
	if err != nil {
		log.Fatal("ListenAndServe:", err)
	}

}
